<?php
/**
* Copyright 2009 Waag Society <http://www.waag.org>
* This file is part of Annotrax.
*
* Annotrax is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
*
* Annotrax is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Annotrax.
* If not, see http://www.gnu.org/licenses/gpl.html
*/

?>
<?php
/**
 * Model for frame. The frame model is used to provide a screenshot with each annotation.
 * Frames are extra properties for annotations.
 *
 * @todo Frames should be properties of a movie. Thus, they have a timecode and a movie id.
 * They should not be dependent on an annotation!
 *
 * @author Matthijs van Henten  <Matthijs@waag.org>
 * @license GNU GPL 2.0
 * @verson 0.1
 * @copyright Copyright (c) 2009, Waag Society
 */
class Default_Model_Frame{
	const DEFAULT_MOVIE_PATH	= 'public/movies';
	const DEFAULT_THUMBNAIL_SIZE = '128x128';
	const DEFAULT_ICON_SIZE		 = '32x32';

    // data
	private $id;
	private $movieId;

	private $timeCode;
    private $thumbnail;
    private $vignette;	
    private $image;
	private $icon;

    private $width;
    private $height;
    private $mimeType;

	private $output;
    private $inserted;

    // properties
    private $mapper;
	private $movie;

    /**
     * Constructor for Model_Frame. construction arguments may be given as an array
     * and will be passed trough __set
     *
     * @param array $args array with options
     */
    public function __construct( array $args = array() ){
		foreach( $args as $key => $value ){
			$this->__set( $key, $value );
		}
    }

    public function __set( $name, $value ){
		$name = $this->camelize( $name );
		if( property_exists( $this, $name ) ){
			//findByMovieAndTime
			if( ( $method = 'set' . ucfirst( $name ) ) && method_exists( $this, $method ) ){
				call_user_func( array( $this, $method ), $value );
			}
			else{
				$this->$name = $value;
			}
		}
    }

    public function __get( $name ){
        if( ( $method = 'get' . ucfirst( $name ) ) && method_exists( $this, $method ) ){
            return $this->$method();
        }
        else if( property_exists( $this, $name ) ){
            if( null === $this->$name ){
                $this->find();
            }
            return $this->$name;
        }
    }

	private function camelize( $string ){
		$string = join( '', array_map( 'ucfirst', explode( '_', $string ) ) );
		$string{0} = strtolower( $string{0} );
		return $string;
	}

	public function setMimeType( $mimeType ){
		$this->mimeType = (string) $mimeType;
	}

	public function getMimeType(){
		if( null == $this->mimeType ){
			$this->mimeType = 'image/jpeg';
		}
		return $this->mimeType;
	}

	public function setTimeCode( $timeCode ){
		if( is_numeric( $timeCode ) ){
			$this->timeCode = (int) $timeCode;
		}
	}

	public function getTimeCode(){
		if( null == $this->timeCode ){
			$this->timeCode = 1;
		}
		return $this->timeCode;
	}

	public function setMovie( Default_Model_Movie $movie ){
		$this->movie 	= $movie;
		$this->movieId 	= $movie->id;
	}

	public function getMovie(){
		if( null == $this->movie ){
			$this->movie = new Default_Model_Movie();
		}
		return $this->movie;
	}

    private function find(){
		if( null !== $this->id ){
			$this->getMapper()->find( $this );
		}
		else if( null !== $this->movieId && null !== $this->timeCode ){
			$this->getMapper()->findByMovieAndTime( $this );
		}

		// nog steeds null?
		if( null === $this->id ){
			$this->create();
		}
    }

	/**
	 * Create new thumbnail images
	 */
	private function create(){
		$gd = new Ogg_Thumb( array(
			'timeCode' 	=> $this->getTimeCode(),
			'movie'		=> $this->getMoviePath()
		));

		$iconSize = explode( 'x', self::DEFAULT_ICON_SIZE );
		$thumbSize = explode( 'x', self::DEFAULT_THUMBNAIL_SIZE );

		$this->width  = $gd->getWidth();
		$this->height = $gd->getHeight();

		$this->image 	 = $gd->getThumbnail();
		$this->thumbnail = $gd->getThumbnail( $thumbSize[0], $thumbSize[1] );
		$this->vignette  = $gd->getThumbnail( round($this->width/2), round($this->height/2) );
		$this->icon      = $gd->getThumbnail($iconSize[0], $iconSize[1]);

		$this->output =  $gd->getLog();
	}

    public function save(){
		$this->getMapper()->save( $this );
    }

    /**
     * retrieve PATH for movies.
     * This function is a placeholder for a generic approach.
     *
     * @return string $path
     */
    private function getMoviePath(){
		$filename = $this->getMovie()->filename;

		if( ! empty( $filename ) ){
			$path = array(str_replace( '/application', '', APPLICATION_PATH ) );
			if( defined( 'MOVIE_PATH' ) ){
				$path[] = MOVIE_PATH;
			}
			else{
				$path[] = self::DEFAULT_MOVIE_PATH;
			}

			$path[] = $filename;

			return join( '/', $path );
		}
    }

    /**
     * Fetch or instantiates the mapper
     *
     * @return object default_model_mapper
     */
    private function getMapper(){
        if( $this->mapper === null ){
            $mapperName = get_class( $this ) . 'Mapper';
            $this->setMapper( new $mapperName() );
        }

        return $this->mapper;
    }

    /**
     * Set mapper
     *
     * @param default_model_mapper $mapper
     */
    private function setMapper( $mapper ){
        $instanceName = get_class( $this ) . 'Mapper';
        if( $mapper instanceof $instanceName ){
            $this->mapper = $mapper;
        }
    }
}
